package dawnland03.model.task;

import dawnland03.model.action.parameter.ActionOutputParam;
import dawnland03.model.action.parameter.OutputParameters;
import dawnland03.model.entity.Entity;

import java.util.*;

/**
 * User: Petru Obreja (obrejap@yahoo.com)
 * Date: Jan 21, 2010
 * Time: 11:00:22 PM
 */
public class GroupTask extends Task {
    protected LinkedList<Task> handledTasks;
    protected LinkedList<Task> unhandledTasks;
    protected Task currentTask;

    public GroupTask(String name, Entity entity) {
        super(name, entity);
        initGroupTask();
    }

    private void initGroupTask() {
        handledTasks = new LinkedList<Task>();
        unhandledTasks = new LinkedList<Task>();
        currentTask = null;
    }

    @Override
    protected void doNextStep() {
        if (getTaskStatus() == TaskStatus.RUNNING) {
            while (unhandledTasks.size() > 0) {
                if (currentTask != null) {
                    if (currentTask.getTaskStatus() == TaskStatus.getLastStatus()) {
                        handledTasks.add(currentTask);
                        unhandledTasks.remove(currentTask);
                    }
                }
                if (unhandledTasks.size() > 0) {
                    currentTask = unhandledTasks.getFirst();
                    currentTask.doNextStep();
                }
            }
        }
        super.doNextStep();
    }

    protected final boolean isGroupTask() {
        return true;
    }

    public void addTask(Task task) {
        unhandledTasks.add(task);
        task.setParentTask(this);
    }

    public void addTaskFirst(Task task) {
        unhandledTasks.addFirst(task);
        task.setParentTask(this);
    }

    public void addTaskLast(Task task) {
        unhandledTasks.addLast(task);
        task.setParentTask(this);
    }

    public void duplicateTaskAndAddFirst(Task originalTask) {
        Task duplicatedTask = originalTask.duplicate();
        addTaskFirst(duplicatedTask);
    }

    /*
     Removes all unhandled tasks and all parent's unhandled tasks.
     */
    public void cancelTask(){
        unhandledTasks.clear();
        if(getParentTask()!=null){
            getParentTask().cancelTask();
        }
    }

    @Override
    protected Task duplicate() {
        GroupTask duplicatedGroupTask = new GroupTask(this.name, this.entity);
        for (Map.Entry<TaskStatus, TaskCondition> statusTaskConditionEntry : afterStatusCondition.entrySet()) {
            duplicatedGroupTask.addTaskConditionAfterTaskStatus(statusTaskConditionEntry.getKey(), statusTaskConditionEntry.getValue());
        }
        for (Task task : handledTasks) {
            duplicatedGroupTask.addTask(task.duplicate());
        }
        for (Task task : unhandledTasks) {
            duplicatedGroupTask.addTask(task.duplicate());
        }
        return duplicatedGroupTask;
    }
}
